﻿using UnityEngine;
using System.Collections.Generic;

namespace EchoFramework
{
    /// <summary>
    /// 有限状态机系统
    /// </summary>
    public class FSMSystem
    {
        /// <summary>
        /// 有限状态机字典
        /// key:状态枚举
        /// value:状态对象
        /// </summary>
        private Dictionary<FSMStateEnum, FSMState> fsmStateDict = new Dictionary<FSMStateEnum, FSMState>();
        /// <summary>
        /// 当前状态
        /// </summary>
        private FSMState curState = null;
        /// <summary>
        /// 属于的对象
        /// </summary>
        private GameObject owner;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="owner">属于的对象</param>
        public FSMSystem(GameObject owner)
        {
            this.owner = owner;
        }

        /// <summary>
        /// 持续调用
        /// </summary>
        public void OnUpdate()
        {
            curState?.OnUpdate();
            curState?.OnReason();
        }

        /// <summary>
        /// 添加状态
        /// </summary>
        /// <param name="state">状态</param>
        public void AddFSMState(FSMState state)
        {
            if (state == null)
            {
                GameLogger.LogWarning(string.Format("{0} 添加的状态为Null!", owner), owner);
                return;
            }
            if (state.stateEnum == FSMStateEnum.Null)
            {
                GameLogger.LogWarning(string.Format("{0} 添加的状态枚举为Null", owner), owner);
                return;
            }
            if (fsmStateDict.ContainsKey(state.stateEnum))
            {
                GameLogger.LogWarning(string.Format("{0} 已存在状态枚举 {1}", owner, state.stateEnum), owner);
                return;
            }
            fsmStateDict.Add(state.stateEnum, state);
        }

        /// <summary>
        /// 删除状态
        /// </summary>
        /// <param name="state">状态</param>
        public void DeleteState(FSMState state)
        {
            if (state == null)
            {
                GameLogger.LogWarning(string.Format("{0} 删除的状态为Null!", owner), owner);
                return;
            }
            DeleteState(state.stateEnum);
        }

        /// <summary>
        /// 删除状态
        /// </summary>
        /// <param name="state">状态枚举</param>
        public void DeleteState(FSMStateEnum stateEnum)
        {
            if (stateEnum == FSMStateEnum.Null)
            {
                GameLogger.LogWarning(string.Format("{0} 删除的状态枚举为Null", owner), owner);
                return;
            }
            if (!fsmStateDict.ContainsKey(stateEnum))
            {
                GameLogger.LogWarning(string.Format("{0} 不存在状态枚举 {1}", owner, stateEnum), owner);
                return;
            }
            fsmStateDict.Remove(stateEnum);
        }

        /// <summary>
        /// 转换到下一个状态
        /// </summary>
        /// <param name="transition">过渡条件</param>
        public void TransitionState(FSMTransitionEnum transition)
        {
            if (curState == null)
            {
                GameLogger.LogWarning(string.Format("{0} 当前状态为Null", owner), owner);
                return;
            }
            if (transition == FSMTransitionEnum.Null)
            {
                GameLogger.LogWarning(string.Format("{0} 调用转换时，过渡条件枚举为Null", owner), owner);
                return;
            }
            FSMStateEnum nextStateEnum = curState.GetNextState(transition);
            if (nextStateEnum == FSMStateEnum.Null)
            {
                GameLogger.LogWarning(string.Format("{0} 调用转换时，下一个状态枚举为Null", owner), owner);
                return;
            }
            if(!fsmStateDict.ContainsKey(nextStateEnum))
            {
                GameLogger.LogWarning(string.Format("{0} 调用转换时，下一个状态枚举为 {1} 不存在", owner, nextStateEnum), owner);
                return;
            }
            curState.OnExit();
            curState = fsmStateDict[nextStateEnum];
            curState.OnEnter();
        }

        /// <summary>
        /// 设置FSM启动时第一个状态
        /// </summary>
        /// <param name="state">默认状态</param>
        public void SetDefaultState(FSMState state)
        {
            if(state == null || state.stateEnum == FSMStateEnum.Null || !fsmStateDict.ContainsKey(state.stateEnum))
            {
                GameLogger.LogError(string.Format("{0} 设置默认状态失败！", owner), owner);
                return;
            }
            curState = state;
        }
    }
}
